package cn.xuqiudong.demo.pdf;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;

/**
 * 描述:
 *
 * @author Vic.xu
 * @since 2025-04-01 17:35
 */
public class PdfWatermarkUtils {

    /**
     * 添加双重隐藏水印（文本水印 + 元数据水印）
     * @param inputPath   输入PDF路径
     * @param outputPath  输出PDF路径
     * @param textWatermark  文本水印内容（如："SECRET:12345"）
     * @param metadataKey    元数据键（如："VerificationCode"）
     * @param metadataValue  元数据值（如："HIDDEN_67890"）
     */
    public static void addDualWatermark(
            String inputPath,
            String outputPath,
            String textWatermark,
            String metadataKey,
            String metadataValue
    ) throws IOException {
        PDDocument doc = PDDocument.load(new File(inputPath));

        // 1. 添加透明文本水印
        addInvisibleTextWatermark(doc, textWatermark);

        // 2. 添加元数据水印
        addMetadataWatermark(doc, metadataKey, metadataValue);

        // 保存PDF
        doc.save(new File(outputPath));
        doc.close();
    }

    // 添加透明文本水印（私有方法）
    private static void addInvisibleTextWatermark(PDDocument doc, String watermarkText) throws IOException {
        PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
        graphicsState.setNonStrokingAlphaConstant(0.01f); // 透明度1%

        for (PDPage page : doc.getPages()) {
            PDPageContentStream contentStream = new PDPageContentStream(
                    doc, page, PDPageContentStream.AppendMode.APPEND, true
            );
            contentStream.setGraphicsStateParameters(graphicsState);
            contentStream.setFont(PDType1Font.HELVETICA, 8);
            contentStream.beginText();
            contentStream.newLineAtOffset(20, 20); // 左下角坐标
            contentStream.showText(watermarkText);
            contentStream.endText();
            contentStream.close();
        }
    }

    // 添加元数据水印（私有方法）
    private static void addMetadataWatermark(PDDocument doc, String key, String value) {
        PDDocumentInformation info = doc.getDocumentInformation();
        info.setCustomMetadataValue(key, value);
    }

    /**
     * 生成动态水印内容（示例）
     */
    public static String generateDynamicWatermark(String userId) {
        return String.format("UID:%s_DATE:%s_RAND:%d",
                userId,
                LocalDate.now(),
                (int) (Math.random() * 10000)
        );
    }

    // 示例用法
    public static void main(String[] args) throws IOException {
        // 动态生成水印内容
        String textWatermark = generateDynamicWatermark("Alice");

        // 添加双重水印
        addDualWatermark(
                "D:\\desk\\4.pdf",
                "D:\\desk\\4-1.pdf",
                textWatermark,                  // 文本水印
                "SecurityCode",                 // 元数据键
                "HIDDEN_" + System.currentTimeMillis()  // 元数据值
        );
        System.out.println("PDF水印添加完成！");
    }
}
